package sanduche.play.generators

import java.io.File
import java.io.PrintWriter

object STJSGenerator {

  def apply(modules: Seq[SanModule]) {
    val file = new File("client-app/client/common/EndPoints.java")
    if (!file.exists())
      file.createNewFile();
    val pw = new PrintWriter(file);
    pw.print(s"""package client.common;
    		|import org.stjs.javascript.annotation.STJSBridge;
    		|import org.stjs.javascript.Array;
    		|import client.common.javascript.*;
    		|import client.common.angular.*;
    		|import client.common.Models.*;
    		|import vos.*;
    		|
    		|@STJSBridge
    		|public interface EndPoints{
    			${
      modules.map { module =>
        toSTJSModule(module);
      }.mkString("\n    		|	")
    }
    		|}""".stripMargin)
    pw.close

  }
  def toSTJSModule(module: SanModule) = {
    "public static interface " ++ module.name.capitalize ++ "EP {" ++
      module.services.map { service =>
        toSTJSCallbacks(service);
      }.mkString("\n") ++ "\n}";
  }

  def toSTJSCallbacks(service: SanService) = {
    val returnType = if (service.returns) {
      if (service.returnType.isIterable) { "Array" ++ service.returnType.maybeGenericType.map("<" ++ _.getSimpleName() ++ ">").getOrElse("") }
      else { service.returnType.rawType.getSimpleName() }
    } else "EmptyPromise";
    val params: List[String] = List(service.urlParams.map { param =>
      param.declaration
    }: _*) ++ (service.maybeBody.map { body =>
      ((if (body.epType.isIterable) {
        "Array" ++ body.epType.maybeGenericType.map {
          "<" ++ _.getSimpleName() ++ ">"
        }.getOrElse("")
      } else { body.epType.rawType.getSimpleName() }) ++ " body")
    }).toList
    s"""
    |		public $returnType ${service.simpleName}(${params.mkString(", ")});
    |		public $returnType ${service.simpleName}(${(params ::: List(s"JsProcedure1<$returnType> callback")).mkString(", ")});
    |		public $returnType ${service.simpleName}(${(params ::: List(s"JsProcedure1<$returnType> callback,JsProcedure1<ErrorObject> error")).mkString(", ")});""".stripMargin;
  }

}